package answer_1_10

import "fmt"

//将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行 Z 字形排列。
//比如输入字符串为 "PAYPALISHIRING" 行数为 3 时，排列如下：
//P   A   H   N
//A P L S I I G
//Y   I   R
//之后，你的输出需要从左往右逐行读取，产生出一个新的字符串，比如："PAHNAPLSIIGYIR"。
//请你实现这个将字符串进行指定行数变换的函数：
//string convert(string s, int numRows);

//示例 1：
//输入：s = "PAYPALISHIRING", numRows = 3
//输出："PAHNAPLSIIGYIR"

//示例 2：
//输入：s = "PAYPALISHIRING", numRows = 4
//输出："PINALSIGYAHRPI"
//解释：
//P     I    N
//A   L S  I G
//Y A   H R
//P     I

//示例 3：
//输入：s = "A", numRows = 1
//输出："A"

//提示：
//1 <= s.length <= 1000
//s 由英文字母（小写和大写）、',' 和 '.' 组成
//1 <= numRows <= 1000

func Answer_6() {
	fmt.Println(convert_1("PAYPALISHIRING", 3))
}

func convert_1(s string, numRows int) string {
	// 不满足，提前返回
	if len(s) <= 2 || numRows == 1 {
		return s
	}
	// 保存最终结果
	var res string
	// 保存每次的结果
	var tmp = make([]string, numRows)
	// 初始位置
	curPos := 0
	// 用来标记是否该转向了
	shouldTurn := -1
	// 遍历每个元素
	for _, val := range s {
		// 添加进tmp里面，位置为curPos
		tmp[curPos] += string(val)
		// 如果走到头或者尾，就该转向了
		// 因为就在numRows的长度里面左右震荡
		if curPos == 0 || curPos == numRows-1 {
			// 转向
			shouldTurn = -shouldTurn
		}
		// curPos 用来标记tmp里面我们该去哪个位置
		curPos += shouldTurn
	}
	// 这时tmp里面已经保存了数据了，我们只需要转换一下输出格式
	for _, val := range tmp {
		res += val
	}
	// 最后的输出
	return res
}

func convert_2(s string, numRows int) string {
	if numRows == 1 {
		return s
	}
	ans := []byte{}
	for i, n := 0, len(s); i < numRows; i++ {
		if i == 0 || i == numRows-1 {
			for j := i; j < n; j += numRows*2 - 2 {
				ans = append(ans, s[j])
			}
		} else {
			for j, cur := i, 0; j < n; cur ^= 1 {
				ans = append(ans, s[j])
				if cur == 0 {
					j += (numRows - 1 - i) * 2
				} else {
					j += i * 2
				}
			}
		}
	}
	return string(ans)
}
